#pragma once

#ifndef _PARTICLE_T_DEFINE
#define _PARTICLE_T_DEFINE

#include <list>
#include "mtxlib.h"

namespace Particles
{

		struct particle_t 
		{ 
		  float age;    // time elapsed from particle's creation in seconds 
		  float size;   // billboard's size; 
		  vector3 velocity;  // particle's velocity vector 
		  vector3 position;  // particle's position 
		  float rotation;  // billboard's rotation in degrees (screen space) 
		  float rvelocity;  // billboard's rotational velocity in degrees 

		  void draw( const vector4 & invCameraPos, const matrix44 & invViewMatrix);
		}; 

		struct ParticleCameraDistComparer {
			matrix44 cameraMatrix;
			ParticleCameraDistComparer(matrix44 & viewMatrix);
			bool operator() (particle_t i,particle_t j);
		};

		struct ParticleUpdater {
			float dt;
			float size;
			float scale;
		public:
			ParticleUpdater(float psize = 1.0f, float pscale = 1.0f);
			void setDt(float dtime);

			particle_t operator() (particle_t particle);
		};

		struct ParticleDrawer {
			vector4 invCamPos;
			matrix44 invViewMatrix;
		public:
			ParticleDrawer(vector4 camPos, matrix44 viewMatrix);

			void operator() (particle_t particle);
		};

		struct ParticleRemover {
			float ttl;
		public:
			ParticleRemover(float timeToLive = 1.0);
			void setTTL(float timeToLive);

			bool operator() (particle_t particle);
		};
		
		bool removeParticle (particle_t p);
		void drawSquare();

	class ParticleSystem{
	public:
		ParticleSystem(void);
		void update_particles(float time);
		void render_particles(const vector4 & cameraPosition, const matrix44 & viewMatrix);
	protected:
		// Particle system's parameters copied from OGRE sample 
		float time_to_live;
		// time of particles's life in seconds 
 
		float emission_rate;
		// number of particle's to be born per second 
 
		vector3 direction;   
		// mean direction of particle's velocity 
 
		float angle; 
		// maximal angle declination from mean direction in degrees 
 
		float velocity_min;
		// minimal value of particle's velocity 
 
		float velocity_max; 
		// maximal value of particle's velocity 
 
		float size;     
		// initial size of particle 
 
		float scale;   
		// size' = size+size*scale*time 
 
		float rotation_speed_min;
		// minimal rotation speed in angles per second 
 
		float rotation_speed_max;  
		// maximal rotation speed in angles per second 

		float last_emision_time;
		float emission_freq;

		int max_particles;

		vector3 source_position;
		
		ParticleUpdater updater;
		ParticleRemover remover;
		std::list<particle_t> particlesList;
		// all particles

		float rand_FloatRange(float a, float b);


		void init();
	};
}

#endif